package pub

import (
	"fmt"
	"net/url"
	"time"

	"gitee.com/chenrh/finego/app"
	"gitee.com/chenrh/finego/backends/models"
	"gitee.com/chenrh/finego/backends/utils"
	"gitee.com/chenrh/gotoolkit/hash"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
)

type LoginController struct {
	// Optionally: context is auto-binded by Iris on each request,
	// remember that on each incoming request iris creates a new UserController each time,
	// so all fields are request-scoped by-default, only dependency injection is able to set
	// custom fields like the Service which is the same for all requests (static binding).
	Ctx iris.Context
}

func (c *LoginController) GetLogin() mvc.Result {
	fromuri := c.Ctx.URLParam("from")
	if len(fromuri) == 0 {
		fromuri = "/"
	}

	dingdingCallBackURL := url.QueryEscape("http://wx.chenrh.com/dd/login")

	dingdingurl := fmt.Sprintf("https://login.dingtalk.com/oauth2/auth?redirect_uri=%s", dingdingCallBackURL)
	dingdingurl += "&response_type=code"
	dingdingurl += "&client_id=dingtjzgjyrj8rvjlakk"
	dingdingurl += "&scope=openid"
	dingdingurl += "&state=1"
	dingdingurl += "&prompt=consent"

	// 增加验证码
	capt := utils.Captcha(4)
	return mvc.View{
		Name: "pub/login/login.html",
		Data: iris.Map{
			"Title":       "登录 | " + app.AppConfig.AppName,
			"CaptchaPath": capt.Path,
			"CaptchaId":   capt.ID,
			"FromUri":     fromuri,
			"DDURL":       dingdingurl,
		},
	}
}

// GetLogout 退出登录
func (c *LoginController) GetLogout() {
	utils.DestroySession(c.Ctx)
	c.Ctx.Redirect("/pub/login")
}

func (c *LoginController) GetRegister() interface{} {
	return "此功能开中发……"
	// return mvc.View{
	// 	Name: "/pub/login/register.html",
	// 	Data: iris.Map{"Title": "注册 | " + app.AppConfig.AppName},
	// }
}

func (c *LoginController) PostLogin() {

	loginJSON := make(map[string]string)
	err := c.Ctx.ReadJSON(&loginJSON)

	usercode := loginJSON["usercode"]
	password := loginJSON["userpass"]
	usercapt := loginJSON["usercapt"]
	captcha_id := loginJSON["captcha_id"]

	if len(usercode) == 0 {
		c.responseToClient(false, "请输入您的帐号")
		return
	}

	if len(password) == 0 {
		c.responseToClient(false, "密码不允许为空")
		return
	}

	if len(usercapt) == 0 {
		c.responseToClient(false, "请输入验证码")
		return
	}

	if len(captcha_id) == 0 {
		c.responseToClient(false, "非法请求")
		return
	}

	// 验证码错误，重新生成验证码 id
	capt := utils.Captcha(4)

	if !utils.VerifyCaptcha(captcha_id, usercapt) {
		c.responseToClientCaptcha(false, "验证码错误", capt)
		return
	}

	loginlog := models.PUB_USER_LOG{
		NickName:  "尝试登录者",
		UserCode:  usercode,
		LogInfo:   "尝试登录",
		LogIP:     c.Ctx.RemoteAddr(),
		UserAgent: c.Ctx.GetHeader("user-agent"),
	}

	user := models.PUB_USER{}
	user, err = user.GetModelByUserCode(usercode)
	if err != nil {
		loginlog.LogInfo = err.Error()
		go user.InsertLoginLog(loginlog)
		c.responseToClientCaptcha(false, "用户名或密码错误", capt)
		return
	}

	password = hash.Md5Encode(password + user.LoginSalt)
	if password != user.LoginPass {
		loginlog.LogInfo = "用户名或密码错误"
		go user.InsertLoginLog(loginlog)
		c.responseToClientCaptcha(false, loginlog.LogInfo, capt)
		return
	}

	if user.LoginLimit == 1 {
		loginlog.LogInfo = "此帐号被限制登录"
		go user.InsertLoginLog(loginlog)
		c.responseToClientCaptcha(false, loginlog.LogInfo, capt)
		return
	}

	var userCache = utils.UserCacheModel{
		IsLogin:  true,
		UserID:   user.UserId,
		UserCode: user.UserCode,
		NickName: user.NickName,
	}

	// 1. 设置 session
	utils.SetSession(c.Ctx, utils.SessionKeyLoginUser, userCache)

	// 过期时间
	expire := 24 * 30 * time.Hour
	c.Ctx.SetCookieKV("USER_NAME", user.UserCode, iris.CookieExpires(expire), iris.CookieHTTPOnly(false))

	loginlog.NickName = user.NickName
	loginlog.LogInfo = "登录成功"
	go user.InsertLoginLog(loginlog)
	c.responseToClient(true, loginlog.LogInfo)
	return
}

func (c *LoginController) responseToClient(flag bool, msg string) {
	isAjax := c.Ctx.IsAjax()
	if !isAjax {
		c.Ctx.JSON(iris.Map{"msg": msg, "flag": flag})
		return
	}
	c.Ctx.JSON(iris.Map{"msg": msg, "flag": flag})
}

func (c *LoginController) responseToClientCaptcha(flag bool, msg string, capt *utils.MyCaptchaModel) {
	isAjax := c.Ctx.IsAjax()
	if !isAjax {
		c.Ctx.JSON(iris.Map{"msg": msg, "flag": flag, "capt": capt})
		return
	}
	c.Ctx.JSON(iris.Map{"msg": msg, "flag": flag, "capt": capt})
}
